﻿using System;

using zijian666.Converts.Abstractions;
using zijian666.Converts.Convertor.Base;
using zijian666.Converts.Core;
using zijian666.Converts.Extensions;

namespace zijian666.Converts.Convertor;

/// <summary>
/// 布尔值转换器
/// </summary>
public class BooleanConvertor : FromConvertor<bool>, IFromConvertible<bool>, IFrom<object, bool>
{
    /// <inheritdoc/>
    public ConvertResult<bool> From(IConvertContext context, bool input) => input;

    /// <inheritdoc/>
    public ConvertResult<bool> From(IConvertContext context, char input) => input != 0;

    /// <inheritdoc/>
    public ConvertResult<bool> From(IConvertContext context, sbyte input) => input != 0;

    /// <inheritdoc/>
    public ConvertResult<bool> From(IConvertContext context, byte input) => input != 0;

    /// <inheritdoc/>
    public ConvertResult<bool> From(IConvertContext context, short input) => input != 0;

    /// <inheritdoc/>
    public ConvertResult<bool> From(IConvertContext context, ushort input) => input != 0;

    /// <inheritdoc/>
    public ConvertResult<bool> From(IConvertContext context, int input) => input != 0;

    /// <inheritdoc/>
    public ConvertResult<bool> From(IConvertContext context, uint input) => input != 0;

    /// <inheritdoc/>
    public ConvertResult<bool> From(IConvertContext context, long input) => input != 0;

    /// <inheritdoc/>
    public ConvertResult<bool> From(IConvertContext context, ulong input) => input != 0;

    /// <inheritdoc/>
    public ConvertResult<bool> From(IConvertContext context, float input) => input != 0;

    /// <inheritdoc/>
    public ConvertResult<bool> From(IConvertContext context, double input) => input != 0;

    /// <inheritdoc/>
    public ConvertResult<bool> From(IConvertContext context, decimal input) => input != 0;

    /// <inheritdoc/>
    public ConvertResult<bool> From(IConvertContext context, string input)
    {
        var s = input.Trim();

        return s.Length switch
        {
            1 when s[0] is '1' or 'T' or 't' or '对' or '對' or '真' or '是' or '男' => new(true),
            1 when s[0] is '0' or 'F' or 'f' or '错' or '錯' or '假' or '否' or '女' => new(false),
            2 when s[0] is '+' or '-' && s[1] is '0' or '1' => new(s[1] == '1'),
            4 when s.Equals("true", StringComparison.OrdinalIgnoreCase) => new(true),
            5 when s.Equals("false", StringComparison.OrdinalIgnoreCase) => new(false),
            _ => (ConvertResult<bool>)context.ConvertFail(this, input),
        };
    }

    /// <inheritdoc/>
    public ConvertResult<bool> From(IConvertContext context, object input) => context.ConvertFail(this, input);

    /// <inheritdoc/>
    public ConvertResult<bool> From(IConvertContext context, DateTime input) => context.ConvertFail(this, input);
}
